package x.ovo.wechat.bot.plugin;

import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.cron.CronUtil;
import x.ovo.wechat.bot.core.Constant;
import x.ovo.wechat.bot.core.command.CommandExcutor;
import x.ovo.wechat.bot.core.contact.Contactable;
import x.ovo.wechat.bot.core.contact.RetrievalType;
import x.ovo.wechat.bot.core.entity.Contact;
import x.ovo.wechat.bot.core.entity.Member;
import x.ovo.wechat.bot.core.enums.ContactType;
import x.ovo.wechat.bot.core.enums.MessageType;
import x.ovo.wechat.bot.core.event.EventListener;
import x.ovo.wechat.bot.core.event.MessageEvent;
import x.ovo.wechat.bot.core.message.TextMessage;
import x.ovo.wechat.bot.core.plugin.Plugin;

import java.io.File;
import java.util.Objects;

@Slf4j(topic = "Scheduler")
public class SchedulerPlugin extends Plugin {
    @Override
    public void onLoad() {
        // 如果配置文件不存在，输出默认配置文件
        File file = FileUtil.file(getDataDir(), Constant.Files.CONFIG_FILE_NAME);
        if (!FileUtil.exists(file)) this.saveDefaultConfig();
        if (CronUtil.getScheduler().isStarted()) CronUtil.stop();
        // 获取配置，创建定时任务
        this.getConfig().values().stream()
                .map(map -> Convert.convert(SchedulerConfig.class, map))
                .forEach(config -> {
                    try {
                        // 创建定时任务
                        CronUtil.schedule(config.getCron(), getRunnable(config));
                    } catch (Exception ex) {
                        log.error("创建定时任务 [{}] 失败，{}", config.getName(), ex.getMessage());
                    }
                });
        CronUtil.start();
    }

    /**
     * 获取执行任务
     *
     * @param config 定时任务配置
     * @return {@link Runnable }
     */
    private Runnable getRunnable(SchedulerConfig config) {
        return () -> {
            // 获取bot拥有人信息
            Contactable owner = this.context.getContactManager().get(this.context.getOwner(), RetrievalType.NICK_NAME);
            // 将owner转为Member对象
            Member member = Convert.convert(Member.class, owner);
            // 遍历联系人
            for (String name : config.getTargets()) {
                // 通过联系人昵称获取联系人对象
                Contact contact = this.context.getContactManager().get(name, RetrievalType.NICK_NAME);
                if (Objects.isNull(contact)) {
                    log.warn("联系人 [{}] 信息不存在，请检查配置文件或将联系人添加到通讯录后重试", name);
                    continue;
                }
                // 构造一个消息，模拟联系人发送消息触发事件
                TextMessage message = new TextMessage();
                message.setFrom(contact);
                message.setType(MessageType.TEXT);
                message.setContent(config.getKeyword());
                message.setTo(this.context.getSession().getContact());
                // 如果是群消息，设置member为owner，避免部分插件权限限制或报错
                if (ContactType.GROUP.equals(contact.getType())) message.setMember(member);
                // 创建消息事件并发布
                new MessageEvent<>(message).fire();
                log.info("定时任务 [{}] 执行完成", config.getName());
            }
        };
    }

    @Override
    public EventListener<?, ?> getEventListener() {
        return null;
    }

    @Override
    public CommandExcutor getCommandExcutor() {
        return new SchedulerExecutor(this);
    }
}
